package br.com.ninjacoders.parse;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import almonds.ParseObject;
import br.com.ninjacoders.modelo.Entidade;
import br.com.ninjacoders.util.Util;
import br.com.ninjacoders.util.UtilRegistroNotas;

public class Convertedor {

	public static List<Entidade> converterListaParaEntidade(List<ParseObject> lista){
		List<Entidade> listaEntidade = new ArrayList<Entidade>();

		for(ParseObject parseObject : lista){
			listaEntidade.add(converterParaEntidade(parseObject));
		}

		return listaEntidade;
	}

	public static Entidade converterParaEntidade(ParseObject o){
		if(Util.vazio(o)){
			return null;
		}
		
		String className = UtilRegistroNotas.recuperarNomeClasse(o.getClassName());

		try {
			Entidade e = (Entidade) Class.forName(className).newInstance();

			if(possuiAnotacaoClasseEntidade(e)){
				preencheAtributos(e, o);

				return e;
			}
			else{
				throw new RuntimeException(Pesquisador.ERRO_SEM_ANOTACAO_CLASSE_TABELA);
			}

		} catch (InstantiationException e) {
			throw new RuntimeException(e.getMessage());
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e.getMessage());
		} catch (ClassNotFoundException e) {
			throw new RuntimeException(e.getMessage());
		}
	}

	private static void preencheAtributos(Entidade e, ParseObject o) {
		Field[] campos = e.getClass().getDeclaredFields();

		for(Field f : campos){
			AtributoColuna coluna = f.getAnnotation(AtributoColuna.class);
			if(Util.preenchido(coluna)){
				if(Util.preenchido(coluna.nomeColuna())){
					f.setAccessible(Boolean.TRUE);
					Object valor = null;
					
					if(f.getType().equals(String.class)){
						valor = o.getString(coluna.nomeColuna());
					}
					if(f.getType().equals(Double.class)){
						valor = o.getDouble(coluna.nomeColuna());
					}
					
					try {
						f.set(e, valor);
					} catch (IllegalArgumentException e1) {
						throw new RuntimeException(e1.getMessage());
					} catch (IllegalAccessException e1) {
						throw new RuntimeException(e1.getMessage());
					}
				}
			}
		}

	}

	private static boolean possuiAnotacaoClasseEntidade(Entidade e) {
		return Util.preenchido(e.getClass().getAnnotation(ClasseTabela.class));
	}
}
